{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": [],
      "authorship_tag": "ABX9TyNj5c8GmyQmojeuOR200UJN",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/nceder/qpb4e/blob/main/code/Chapter%2009/Chapter_09.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# 9 Functions"
      ],
      "metadata": {
        "id": "aKXXg4OUANwp"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Basic function definitions"
      ],
      "metadata": {
        "id": "EMwEz0n4AQdw"
      }
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "id": "6rbPmW6tAHow"
      },
      "outputs": [],
      "source": [
        "def fact(n):\n",
        "    '''Return the factorial of the given number.'''\n",
        "    r = 1\n",
        "    while n > 0:\n",
        "        r = r * n\n",
        "        n = n - 1\n",
        "    return r"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "fact(4)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "gP-1o09jAL28",
        "outputId": "456658e5-033e-4bde-89c3-8a212bdfb845"
      },
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "24"
            ]
          },
          "metadata": {},
          "execution_count": 2
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "x = fact(4)\n",
        "x"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "dxgbSk-3AcO6",
        "outputId": "0408afc1-a21e-4757-e6aa-bfbcc1a65a1a"
      },
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "24"
            ]
          },
          "metadata": {},
          "execution_count": 3
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# 9.2 Function parameter options\n",
        "## 9.2.1 positional parameters"
      ],
      "metadata": {
        "id": "GqMzZMzUAjme"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def power(x, y):\n",
        "    r = 1\n",
        "    while y > 0:\n",
        "        r = r * x\n",
        "        y = y - 1\n",
        "    return r\n",
        "\n",
        "power(3, 3)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Y_j5ypxWAe06",
        "outputId": "1068928b-c08c-4f89-83bd-d1faad1d899e"
      },
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "27"
            ]
          },
          "metadata": {},
          "execution_count": 4
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "power(3)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 141
        },
        "id": "d3VjS_-nAy0k",
        "outputId": "4c78043d-001a-4ad7-b0ae-fa0c479fc968"
      },
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "error",
          "ename": "TypeError",
          "evalue": "power() missing 1 required positional argument: 'y'",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-5-1bbb88d7a603>\u001b[0m in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mpower\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
            "\u001b[0;31mTypeError\u001b[0m: power() missing 1 required positional argument: 'y'"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "def power(x, y=2):\n",
        "    r = 1\n",
        "    while y > 0:\n",
        "        r = r * x\n",
        "        y = y - 1\n",
        "    return r\n",
        "\n",
        "power(3, 3)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "zQUwJ-jOA5ss",
        "outputId": "919ca98e-68cf-4383-f4b3-6675278d0c83"
      },
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "27"
            ]
          },
          "metadata": {},
          "execution_count": 6
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "power(3)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "LeRBxx4aBJju",
        "outputId": "8a258139-32e8-4aa2-ccec-c7b9a56ab35a"
      },
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "9"
            ]
          },
          "metadata": {},
          "execution_count": 7
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## 9.2.2 Passing arguments by parameter name\n"
      ],
      "metadata": {
        "id": "ZQWmaQWqBnWp"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "power(y=2, x=3)\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "FgrOUnBcBMWu",
        "outputId": "27166ff8-ddde-4428-f7fb-3802666fc446"
      },
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "9"
            ]
          },
          "metadata": {},
          "execution_count": 8
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## 9.2.3 Variable numbers of arguments"
      ],
      "metadata": {
        "id": "APvi7vVnB0F6"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def maximum(*numbers):    #A\n",
        "    if len(numbers) == 0:\n",
        "        return None\n",
        "    else:\n",
        "        maxnum = numbers[0]   #B\n",
        "        for n in numbers[1:]:\n",
        "            if n > maxnum:\n",
        "                maxnum = n\n",
        "        return maxnum\n",
        "\n",
        "maximum(3, 2, 8)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "0DHZqwYkBlAi",
        "outputId": "c09006ac-d739-43d9-d21f-4689594200ba"
      },
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "8"
            ]
          },
          "metadata": {},
          "execution_count": 9
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "maximum(1, 5, 9, -2, 2)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "V2lis74xClKS",
        "outputId": "dbf2c6b2-2d07-4227-9083-1fd11a099346"
      },
      "execution_count": 10,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "9"
            ]
          },
          "metadata": {},
          "execution_count": 10
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "def example_fun(x, y, **other):  #A\n",
        "    print(f\"x: {x}, y: {y}, keys in 'other': {list(other.keys())}\")\n",
        "    other_total = 0\n",
        "    for k in other.keys():\n",
        "        other_total = other_total + other[k]\n",
        "    print(f\"The total of values in 'other' is {other_total}\")\n",
        "\n",
        "example_fun(2, y=\"1\", foo=3, bar=4)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "8akUOxRYCnpc",
        "outputId": "9dec1f26-3ed8-4e41-921f-efee69e8fe46"
      },
      "execution_count": 11,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "x: 2, y: 1, keys in 'other': ['foo', 'bar']\n",
            "The total of values in 'other' is 7\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Quick Check: Functions and parameters\n",
        "How would you write a function that could take any number of unnamed arguments and print their values out in reverse order?\n",
        "\n",
        "What do you need to do to create a procedure or void function—that is, a function with no return value?\n",
        "\n",
        "**Either don’t return a value (use a bare return) or don't use a return statement at all.**\n",
        "\n",
        "What happens if you capture the return value of a function with a variable?\n",
        "\n",
        "**The only result is that you can use that value, whatever it might be.**"
      ],
      "metadata": {
        "id": "gSGddssPEnYG"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def my_funct(*params):\n",
        "    for i in reversed(params):\n",
        "        print(i)\n",
        "\n",
        "my_funct(1,2,3,4)"
      ],
      "metadata": {
        "id": "q9xkCKV188u9",
        "outputId": "c65803ec-3f8d-4607-8d58-bba81bec98c7",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "4\n",
            "3\n",
            "2\n",
            "1\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "#9.3 Mutable objects as arguments"
      ],
      "metadata": {
        "id": "C0sRoZcGEwOg"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def f(n, list1, list2):\n",
        "   list1.append(3)\n",
        "   list2 = [4, 5, 6]\n",
        "   n = n + 1\n",
        "\n",
        "x = 5\n",
        "y = [1, 2]\n",
        "z = [4, 5]\n",
        "f(x, y, z)\n",
        "x, y, z\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "NSqVDUSlDBTo",
        "outputId": "727907c9-124c-45c6-9b67-9c7aed1e0242"
      },
      "execution_count": 12,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(5, [1, 2, 3], [4, 5])"
            ]
          },
          "metadata": {},
          "execution_count": 12
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "def odd_numbers(test_list, odds):\n",
        "  for number in test_list:\n",
        "    if number % 2:\n",
        "      odds.append(number)\n",
        "  return odds\n",
        "\n",
        "odds = []\n",
        "odds = odd_numbers([1, 5, 7, 9, 10], odds)\n",
        "odds"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "AXfn2ekqJGUI",
        "outputId": "ceeeb02b-60c5-44b3-9d28-e5a01a9773e4"
      },
      "execution_count": 13,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[1, 5, 7, 9]"
            ]
          },
          "metadata": {},
          "execution_count": 13
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "def odd_numbers(test_list, odds=[]):\n",
        "  for number in test_list:\n",
        "    if number % 2:\n",
        "      odds.append(number)\n",
        "  return odds\n",
        "\n",
        "\n",
        "odds = odd_numbers([1, 5, 7, 9, 10])\n",
        "odds"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "f3vmjg5SJ3ZW",
        "outputId": "6ffb5106-a9cb-44dd-8e65-7b9a4f0a6a8f"
      },
      "execution_count": 14,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[1, 5, 7, 9]"
            ]
          },
          "metadata": {},
          "execution_count": 14
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "odds = odd_numbers([1, 5, 7, 9, 10])\n",
        "odds"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "_SB0H3xZKRv9",
        "outputId": "ef070d87-2f72-469e-f617-ea56e3d83d6f"
      },
      "execution_count": 15,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[1, 5, 7, 9, 1, 5, 7, 9]"
            ]
          },
          "metadata": {},
          "execution_count": 15
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Quick Check: Mutable function parameters\n",
        "What would be the result of changing a list or dictionary that was passed into a function as a parameter value? Which operations would be likely to create changes that would be visible outside the function? What steps might you take to minimize that risk?\n",
        "\n",
        "**The changes would persist for future uses of the default parameter. Operations such as adding and deleting elements, as well as changing the value of an element, are particularly likely to be problems. To minimize the risk, it's better not to use mutable types as default parameters.**"
      ],
      "metadata": {
        "id": "4UHGiSN4F3dD"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# 9.4 Local, nonlocal, and global variables"
      ],
      "metadata": {
        "id": "cdVVQ0JfMn9b"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def fact(n):\n",
        "    \"\"\"Return the factorial of the given number.\"\"\"\n",
        "    r = 1\n",
        "    while n > 0:\n",
        "        r = r * n\n",
        "        n = n - 1\n",
        "    return r"
      ],
      "metadata": {
        "id": "S-67BlmFKPiw"
      },
      "execution_count": 16,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "def fun():\n",
        "    global a\n",
        "    a = 1\n",
        "    b = 2\n",
        "\n",
        "a = \"one\"\n",
        "b = \"two\"\n",
        "\n",
        "fun()\n",
        "a\n"
      ],
      "metadata": {
        "id": "lI1kbPaJE30y",
        "outputId": "b7d4b76b-ca61-4e97-f967-44119232083b",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 17,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "1"
            ]
          },
          "metadata": {},
          "execution_count": 17
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "b"
      ],
      "metadata": {
        "id": "epZWmPSO5V6I",
        "outputId": "146fd6a9-76ea-4c12-ecdc-7be01d8b79a0",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 35
        }
      },
      "execution_count": 18,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "'two'"
            ],
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            }
          },
          "metadata": {},
          "execution_count": 18
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# file 9.1 nonlocal.py\n",
        "g_var = 0               #A\n",
        "nl_var = 0               #B\n",
        "print(\"top level-> g_var: {0} nl_var: {1}\".format(g_var, nl_var))\n",
        "def test():\n",
        "    nl_var = 2              #C\n",
        "    print(\"in test-> g_var: {0} nl_var: {1}\".format(g_var, nl_var))\n",
        "    def inner_test():\n",
        "\n",
        "        global g_var         #D\n",
        "        nonlocal nl_var      #E\n",
        "        g_var = 1\n",
        "        nl_var = 4\n",
        "        print(\"in inner_test-> g_var: {0} nl_var: {1}\".format(g_var,\n",
        "                                                              nl_var))\n",
        "\n",
        "    inner_test()\n",
        "    print(\"in test-> g_var: {0} nl_var: {1}\".format(g_var, nl_var))\n",
        "\n",
        "test()\n",
        "print(\"top level-> g_var: {0} nl_var: {1}\".format(g_var, nl_var))\n"
      ],
      "metadata": {
        "id": "4N3JWQ7v5hqj",
        "outputId": "4e133686-57b0-4320-955a-e0e7caa4b808",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 19,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "top level-> g_var: 0 nl_var: 0\n",
            "in test-> g_var: 0 nl_var: 2\n",
            "in inner_test-> g_var: 1 nl_var: 4\n",
            "in test-> g_var: 1 nl_var: 4\n",
            "top level-> g_var: 1 nl_var: 0\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Try This: Global vs. local variables\n",
        "Assuming that `x = 5`, what will be the value of `x` after `funct_1()` below executes? After `funct_2()` executes?\n",
        "\n",
        "```python\n",
        "def funct_1():\n",
        "    x = 3\n",
        "def funct_2():\n",
        "    global x\n",
        "    x = 2\n",
        "```\n",
        "\n",
        "**After calling funct_1(), x will be unchanged; after funct_2(), the value in the global x will be 2.**"
      ],
      "metadata": {
        "id": "araFaj4F7hZB"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "x = 0\n",
        "def funct_1():\n",
        "    x = 3\n",
        "def funct_2():\n",
        "    global x\n",
        "    x = 2\n",
        "\n",
        "funct_1()\n",
        "x"
      ],
      "metadata": {
        "id": "2rKPYfjH7Fs3",
        "outputId": "4b29cf5a-6332-40c0-f007-12b3bb903634",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 20,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "0"
            ]
          },
          "metadata": {},
          "execution_count": 20
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "funct_2()\n",
        "x"
      ],
      "metadata": {
        "id": "GsKpiWX69j6W",
        "outputId": "4e6b36b9-7e4c-4fe8-ae2f-3efbbf100d83",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 21,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "2"
            ]
          },
          "metadata": {},
          "execution_count": 21
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# 9.5 Assigning functions to variables"
      ],
      "metadata": {
        "id": "iwyTwhVT9y64"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def f_to_kelvin(degrees_f):\n",
        "    return 273.15 + (degrees_f - 32) * 5 / 9\n",
        "\n",
        "def c_to_kelvin(degrees_c):\n",
        "    return 273.15 + degrees_c\n",
        "\n",
        "abs_temperature = f_to_kelvin\n",
        "abs_temperature(32)"
      ],
      "metadata": {
        "id": "oEO4YZqi9tFC",
        "outputId": "8570169b-7408-46bf-f3f0-a3e0c4b6c1b8",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 22,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "273.15"
            ]
          },
          "metadata": {},
          "execution_count": 22
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "abs_temperature = c_to_kelvin\n",
        "abs_temperature(0)"
      ],
      "metadata": {
        "id": "Wu1s3Bza95K1",
        "outputId": "e924131a-9d83-4666-bdb2-f38602f717f7",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 23,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "273.15"
            ]
          },
          "metadata": {},
          "execution_count": 23
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "t = {'FtoK': f_to_kelvin, 'CtoK': c_to_kelvin}\n",
        "t['FtoK'](32)"
      ],
      "metadata": {
        "id": "iwb1oMO-97TO",
        "outputId": "467a68bb-75a9-4d37-d6f5-fd4bd22d6030",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 24,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "273.15"
            ]
          },
          "metadata": {},
          "execution_count": 24
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "t['CtoK'](0)"
      ],
      "metadata": {
        "id": "cufUxC57-h8N",
        "outputId": "136e7dac-d3c7-45c5-feb5-8b7dc16eeaa4",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 25,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "273.15"
            ]
          },
          "metadata": {},
          "execution_count": 25
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# 9.6 Lambda expressions"
      ],
      "metadata": {
        "id": "ItyKhCni_OMX"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "t2 = {'FtoK': lambda deg_f: 273.15 + (deg_f - 32) * 5 / 9,\n",
        "      'CtoK': lambda deg_c: 273.15 + deg_c}\n",
        "t2['FtoK'](32)"
      ],
      "metadata": {
        "id": "KOtVDKXd-kjM",
        "outputId": "32684e5d-e52c-42e6-e514-cba779d72a15",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 26,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "273.15"
            ]
          },
          "metadata": {},
          "execution_count": 26
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# 9.7 Generator functions"
      ],
      "metadata": {
        "id": "PUF5mBrx_swm"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def four():\n",
        "    x = 0                    #A\n",
        "    while x < 4:\n",
        "        print(\"in generator, x =\", x)\n",
        "        yield x                            #B\n",
        "        x += 1     #C\n",
        "\n",
        "for i in four():\n",
        "    print(f\"Value from generator {i}\")\n"
      ],
      "metadata": {
        "id": "xQWCAL2S_VnF",
        "outputId": "79af93fa-af0d-4b4d-9040-5c2c5447e4bc",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 27,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "in generator, x = 0\n",
            "Value from generator 0\n",
            "in generator, x = 1\n",
            "Value from generator 1\n",
            "in generator, x = 2\n",
            "Value from generator 2\n",
            "in generator, x = 3\n",
            "Value from generator 3\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "def subgen(x):\n",
        "    for i in range(x):\n",
        "        yield i\n",
        "\n",
        "def gen(y):\n",
        "    yield from subgen(y)\n",
        "\n",
        "for q in gen(6):\n",
        "    print(q)"
      ],
      "metadata": {
        "id": "Uo1Hl8_V_x9e",
        "outputId": "4adf44bf-ccef-4179-edd4-6bb4e073b7df",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 28,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "0\n",
            "1\n",
            "2\n",
            "3\n",
            "4\n",
            "5\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "2 in four()"
      ],
      "metadata": {
        "id": "a88ljC5tBgh_",
        "outputId": "70fcd5ed-1fe7-4e28-cc76-e4bd7c2680f4",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 29,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "in generator, x = 0\n",
            "in generator, x = 1\n",
            "in generator, x = 2\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "True"
            ]
          },
          "metadata": {},
          "execution_count": 29
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "5 in four()"
      ],
      "metadata": {
        "id": "VZn4A5iUBnma",
        "outputId": "a9456aa5-b171-46c2-fcf1-c306afe1ea1d",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 30,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "in generator, x = 0\n",
            "in generator, x = 1\n",
            "in generator, x = 2\n",
            "in generator, x = 3\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "False"
            ]
          },
          "metadata": {},
          "execution_count": 30
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Quick Check: Generator functions\n",
        "What would you need to modify in the previous code for the function `four()`to make it work for any number? What would you need to add to allow the starting point to also be set?\n"
      ],
      "metadata": {
        "id": "gQUpz7faBuBp"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def four(limit):\n",
        "    x = 0\n",
        "    while x < limit:\n",
        "        print(\"in generator, x =\", x)\n",
        "        yield x\n",
        "        x += 1\n",
        "\n",
        "for i in four(4):\n",
        "    print(i)"
      ],
      "metadata": {
        "id": "xx7NX-bSBp12",
        "outputId": "60934702-b25f-4218-d1fe-cb27a780ba43",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "in generator, x = 0\n",
            "0\n",
            "in generator, x = 1\n",
            "1\n",
            "in generator, x = 2\n",
            "2\n",
            "in generator, x = 3\n",
            "3\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# To specify the start:\n",
        "\n",
        "def four(start, limit):\n",
        "    x = start\n",
        "    while x < limit:\n",
        "        print(\"in generator, x =\", x)\n",
        "        yield x\n",
        "        x += 1\n",
        "\n",
        "\n",
        "for i in four(1, 4):\n",
        "    print(i)"
      ],
      "metadata": {
        "id": "GkuaRTl5CfMg",
        "outputId": "8a2dd1c5-26d7-4e26-9496-5d57353d3a3a",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "in generator, x = 1\n",
            "1\n",
            "in generator, x = 2\n",
            "2\n",
            "in generator, x = 3\n",
            "3\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# 9.8 Decorators"
      ],
      "metadata": {
        "id": "JldOpDHQC-rw"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def decorate(func):\n",
        "    print(\"in decorate function, decorating\", func.__name__)\n",
        "    def wrapper_func(*args):\n",
        "        print(\"Executing\", func.__name__)\n",
        "        return func(*args)\n",
        "    return wrapper_func\n",
        "\n",
        "def myfunction(parameter):\n",
        "    print(parameter)\n",
        "\n",
        "myfunction = decorate(myfunction)"
      ],
      "metadata": {
        "id": "IcDaTtP4CFXS",
        "outputId": "03527f4d-d151-4699-b2ce-d52535f47395",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 31,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "in decorate function, decorating myfunction\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "myfunction(\"hello\")"
      ],
      "metadata": {
        "id": "q6PMTP9aDC7U",
        "outputId": "066ab7f7-288e-406a-f613-508153116c75",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 32,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Executing myfunction\n",
            "hello\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "def decorate(func):\n",
        "    print(\"in decorate function, decorating\", func.__name__)\n",
        "    def wrapper_func(*args):\n",
        "        print(\"Executing\", func.__name__)\n",
        "        return func(*args)\n",
        "    return wrapper_func\n",
        "\n",
        "@decorate\n",
        "def myfunction(parameter):\n",
        "    print(parameter)\n",
        "\n"
      ],
      "metadata": {
        "id": "V8_y9fKDDFzl",
        "outputId": "c2cdef51-0118-42db-85dc-6dce14c52562",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 33,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "in decorate function, decorating myfunction\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "myfunction(\"hello\")\n"
      ],
      "metadata": {
        "id": "GRy4AgSxDSoS",
        "outputId": "3554a08a-c326-4376-a254-25d9eeebc5dd",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 34,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Executing myfunction\n",
            "hello\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Try This: Decorators\n",
        "How would you modify the code for the decorator function to remove unneeded messages and enclose the return value of the wrapped function in `\"<html>\"` and `\"</html>\"`, so that `myfunction (\"hello\")` would return `\"<html>hello<html>\"`?\n"
      ],
      "metadata": {
        "id": "k54dOc-iEP2R"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def decorate(func):\n",
        "    def wrapper_func(*args):\n",
        "        def inner_wrapper(*args):\n",
        "                return_value = func(*args)\n",
        "                return \"<html>{}<html>\".format(return_value)\n",
        "\n",
        "        return inner_wrapper(*args)\n",
        "    return wrapper_func\n",
        "\n",
        "@decorate\n",
        "def myfunction(parameter):\n",
        "    return parameter\n",
        "\n",
        "print(myfunction(\"Test\"))"
      ],
      "metadata": {
        "id": "BQEXkTavDUqp",
        "outputId": "e14849e9-5204-4db4-e021-9710158e0bc7",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "<html>Test<html>\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Lab 9: Useful functions\n",
        "Looking back at the labs in chapters 6 and 7, refactor that code into functions for cleaning and processing the data. The goal should be that most of the logic is moved into functions. Use your own judgment as to the types of functions and parameters, but keep in mind that functions should do just one thing, and they shouldn’t have any side effects that carry over outside the function."
      ],
      "metadata": {
        "id": "I3xTXTCTErOZ"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "!wget https://raw.githubusercontent.com/nceder/qpb4e/main/code/Chapter%2006/moby_01.txt &> null  && echo Downloaded\n"
      ],
      "metadata": {
        "id": "wVRT0QHqFgmG",
        "outputId": "1cdfdc74-9467-4a0a-f900-7ccc6458d59f",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Downloaded\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Author's version\n",
        "import string\n",
        "punct = str.maketrans('', '', string.punctuation)\n",
        "\n",
        "def clean_line(line):\n",
        "    \"\"\"changes case and removes punctuation\"\"\"\n",
        "    # make all one case\n",
        "    cleaned_line = line.lower()\n",
        "\n",
        "    # remove punctuation\n",
        "    cleaned_line = cleaned_line.translate(punct)\n",
        "    return cleaned_line\n",
        "\n",
        "\n",
        "def get_words(line):\n",
        "    \"\"\"splits line into words, and rejoins with newlines\"\"\"\n",
        "    words = line.split()\n",
        "    return \"\\n\".join(words) + \"\\n\"\n",
        "\n",
        "\n",
        "def count_words(words):\n",
        "    \"\"\"takes list of cleaned words, returns count dictionary\"\"\"\n",
        "    word_count = {}\n",
        "    for word in words:\n",
        "        count = word_count.setdefault(word, 0)\n",
        "        word_count[word] += 1\n",
        "    return word_count\n",
        "\n",
        "\n",
        "def word_stats(word_count):\n",
        "    \"\"\"Takes word count dictionary and returns top and bottom five entries\"\"\"\n",
        "    word_list = list(word_count.items())\n",
        "    word_list.sort(key=lambda x: x[1])\n",
        "    least_common = word_list[:5]\n",
        "    most_common = word_list[-1:-6:-1]\n",
        "    return most_common, least_common\n",
        "\n",
        "with open(\"moby_01.txt\") as infile, open(\"moby_01_clean.txt\", \"w\") as outfile:\n",
        "    for line in infile:\n",
        "        cleaned_line = clean_line(line)\n",
        "\n",
        "        cleaned_words = get_words(cleaned_line)\n",
        "\n",
        "        # write all words for line\n",
        "        outfile.write(cleaned_words)\n",
        "\n",
        "moby_words = []\n",
        "with open('moby_01_clean.txt') as infile:\n",
        "    for word in infile:\n",
        "        if word.strip():\n",
        "            moby_words.append(word.strip())\n",
        "\n",
        "\n",
        "word_count = count_words(moby_words)\n",
        "\n",
        "most, least = word_stats(word_count)\n",
        "print(\"Most common words:\")\n",
        "for word in most:\n",
        "    print(word)\n",
        "print(\"\\nLeast common words:\")\n",
        "for word in least:\n",
        "    print(word)"
      ],
      "metadata": {
        "id": "f-dZASoeEnQv",
        "outputId": "8783e9dd-598a-43a2-e641-d4c284bffb7e",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Most common words:\n",
            "('the', 14)\n",
            "('i', 9)\n",
            "('and', 9)\n",
            "('of', 8)\n",
            "('is', 7)\n",
            "\n",
            "Least common words:\n",
            "('call', 1)\n",
            "('ishmael', 1)\n",
            "('years', 1)\n",
            "('ago', 1)\n",
            "('never', 1)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Original Colaboratory code"
      ],
      "metadata": {
        "id": "26dyNgfLURDj"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# prompt: Open the file moby_01_clean.txt and use a dictionary to count the\n",
        "#         occurrences of each word. Do not use a Counter. Print the five\n",
        "#         most common words and their number of occurrences. Print the\n",
        "#         five least common words and their number of occurrences.\n",
        "\n",
        "# Open the file and read the text into a variable.\n",
        "with open('moby_01_clean.txt', 'r') as f:\n",
        "  text = f.read()\n",
        "\n",
        "# Split the text into words.\n",
        "words = text.split()\n",
        "\n",
        "# Create a dictionary to count the occurrences of each word.\n",
        "word_counts = {}\n",
        "for word in words:\n",
        "  if word not in word_counts:\n",
        "    word_counts[word] = 0\n",
        "  word_counts[word] += 1\n",
        "\n",
        "# Find the five most common words and their number of occurrences.\n",
        "most_common = sorted(word_counts.items(), key=lambda item: item[1], reverse=True)[:5]\n",
        "\n",
        "# Find the five least common words and their number of occurrences.\n",
        "least_common = sorted(word_counts.items(), key=lambda item: item[1])[:5]\n",
        "\n",
        "# Print the results.\n",
        "print(\"Most common words:\")\n",
        "for word, count in most_common:\n",
        "  print(f\"{word}: {count}\")\n",
        "\n",
        "print(\"\\nLeast common words:\")\n",
        "for word, count in least_common:\n",
        "  print(f\"{word}: {count}\")\n"
      ],
      "metadata": {
        "id": "P4mlDH5uKgbm",
        "outputId": "cb98c0da-b067-4a5c-a263-b020741d0df0",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Most common words:\n",
            "the: 14\n",
            "and: 9\n",
            "i: 9\n",
            "of: 8\n",
            "is: 7\n",
            "\n",
            "Least common words:\n",
            "call: 1\n",
            "ishmael: 1\n",
            "years: 1\n",
            "ago: 1\n",
            "never: 1\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Generated by Colaboratory\n",
        "# prompt: Refactor the code in the previous 2 cells into functions for cleaning\n",
        "#         and processing the data.  The goal should be that most of the logic is\n",
        "#         moved into functions.\n",
        "\n",
        "# Function to clean a line of text by converting it to lowercase and removing punctuation\n",
        "def clean_line(line):\n",
        "  line = line.lower()\n",
        "  line = line.translate(str.maketrans('', '', string.punctuation))\n",
        "  return line\n",
        "\n",
        "# Function to split a line of text into words and write each word to a new line in a file\n",
        "def write_words_to_file(line, output_file):\n",
        "  words = line.split()\n",
        "  for word in words:\n",
        "    output_file.write(word + '\\n')\n",
        "\n",
        "# Function to count the occurrences of each word in a list of words\n",
        "def count_word_occurrences(words):\n",
        "  word_counts = {}\n",
        "  for word in words:\n",
        "    if word not in word_counts:\n",
        "      word_counts[word] = 0\n",
        "    word_counts[word] += 1\n",
        "  return word_counts\n",
        "\n",
        "# Function to find the most and least common words in a dictionary of word counts\n",
        "def find_most_and_least_common_words(word_counts):\n",
        "  most_common = sorted(word_counts.items(), key=lambda item: item[1], reverse=True)[:5]\n",
        "  least_common = sorted(word_counts.items(), key=lambda item: item[1])[:5]\n",
        "  return most_common, least_common\n",
        "\n",
        "# Open the input file for reading\n",
        "with open('moby_01.txt', 'r') as input_file:\n",
        "  # Open the output file for writing\n",
        "  with open('moby_01_clean.txt', 'w') as output_file:\n",
        "    # Iterate over each line in the input file\n",
        "    for line in input_file:\n",
        "      # Clean the line of text\n",
        "      clean_line = clean_line(line)\n",
        "\n",
        "      # Write each word in the clean line to the output file\n",
        "      write_words_to_file(clean_line, output_file)\n",
        "\n",
        "# Open the file and read the text into a variable.\n",
        "with open('moby_01_clean.txt', 'r') as f:\n",
        "  text = f.read()\n",
        "\n",
        "# Split the text into words.\n",
        "words = text.split()\n",
        "\n",
        "# Count the occurrences of each word.\n",
        "word_counts = count_word_occurrences(words)\n",
        "\n",
        "# Find the most and least common words.\n",
        "most_common, least_common = find_most_and_least_common_words(word_counts)\n",
        "\n",
        "# Print the results.\n",
        "print(\"Most common words:\")\n",
        "for word, count in most_common:\n",
        "  print(f\"{word}: {count}\")\n",
        "\n",
        "print(\"\\nLeast common words:\")\n",
        "for word, count in least_common:\n",
        "  print(f\"{word}: {count}\")\n"
      ],
      "metadata": {
        "id": "qBm8ZFgBKlHw",
        "outputId": "c036b747-5e9e-4566-e213-72a7495e6a54",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 211
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "error",
          "ename": "TypeError",
          "evalue": "'str' object is not callable",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-7-dd9d43b3f3c2>\u001b[0m in \u001b[0;36m<cell line: 34>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     38\u001b[0m     \u001b[0;32mfor\u001b[0m \u001b[0mline\u001b[0m \u001b[0;32min\u001b[0m \u001b[0minput_file\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     39\u001b[0m       \u001b[0;31m# Clean the line of text\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 40\u001b[0;31m       \u001b[0mclean_line\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mclean_line\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mline\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     41\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     42\u001b[0m       \u001b[0;31m# Write each word in the clean line to the output file\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mTypeError\u001b[0m: 'str' object is not callable"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Original Copilot code"
      ],
      "metadata": {
        "id": "v-ZHQhgTUMLH"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Generated using CoPilot\n",
        "# Prompt: or every line the file moby_01.txt, make everything lower case,\n",
        "#         remove punctuation, and split into words.\n",
        "#         Write the words one per line to the file moby_01_clean.txt.\n",
        "\n",
        "import string\n",
        "\n",
        "# Open the input file for reading\n",
        "with open('moby_01.txt', 'r') as input_file:\n",
        "    # Open the output file for writing\n",
        "    with open('moby_01_clean.txt', 'w') as output_file:\n",
        "        # Iterate over each line in the input file\n",
        "        for line in input_file:\n",
        "            # Convert the line to lowercase\n",
        "            line = line.lower()\n",
        "\n",
        "            # Remove punctuation from the line\n",
        "            line = line.translate(str.maketrans('', '', string.punctuation))\n",
        "\n",
        "            # Split the line into words\n",
        "            words = line.split()\n",
        "\n",
        "            # Write each word to the output file\n",
        "            for word in words:\n",
        "                output_file.write(word + '\\n')\n"
      ],
      "metadata": {
        "id": "dku1spg7E9pD"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# Generated by Copilot\n",
        "import string\n",
        "\n",
        "def clean_line(line):\n",
        "    # Convert the line to lowercase\n",
        "    line = line.lower()\n",
        "\n",
        "    # Remove punctuation from the line\n",
        "    line = line.translate(str.maketrans('', '', string.punctuation))\n",
        "\n",
        "    return line\n",
        "\n",
        "def write_words_to_file(words, output_file):\n",
        "    # Write each word to the output file\n",
        "    for word in words:\n",
        "        output_file.write(word + '\\n')\n",
        "\n",
        "def count_word_occurrences(words):\n",
        "    # Count the occurrences of each word using a dictionary\n",
        "    word_counts = {}\n",
        "    for word in words:\n",
        "        if word in word_counts:\n",
        "            word_counts[word] += 1\n",
        "        else:\n",
        "            word_counts[word] = 1\n",
        "\n",
        "    return word_counts\n",
        "\n",
        "def print_common_words(word_counts, n):\n",
        "    # Sort the word counts in descending order\n",
        "    sorted_word_counts = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)\n",
        "\n",
        "    # Print the n most common words and their occurrences\n",
        "    print(f\"{n} most common words:\")\n",
        "    for word, count in sorted_word_counts[:n]:\n",
        "        print(f\"{word}: {count}\")\n",
        "\n",
        "def print_least_common_words(word_counts, n):\n",
        "    # Sort the word counts in descending order\n",
        "    sorted_word_counts = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)\n",
        "\n",
        "    # Print the n least common words and their occurrences\n",
        "    print(f\"{n} least common words:\")\n",
        "    for word, count in sorted_word_counts[-n:]:\n",
        "        print(f\"{word}: {count}\")\n",
        "\n",
        "def process_file(input_file_path, output_file_path):\n",
        "    # Open the input file for reading\n",
        "    with open(input_file_path, 'r') as input_file:\n",
        "        # Open the output file for writing\n",
        "        with open(output_file_path, 'w') as output_file:\n",
        "            # Iterate over each line in the input file\n",
        "            for line in input_file:\n",
        "                # Clean the line\n",
        "                cleaned_line = clean_line(line)\n",
        "\n",
        "                # Split the line into words\n",
        "                words = cleaned_line.split()\n",
        "\n",
        "                # Write the words to the output file\n",
        "                write_words_to_file(words, output_file)\n",
        "\n",
        "def main():\n",
        "    input_file_path = 'moby_01.txt'\n",
        "    output_file_path = 'moby_01_clean.txt'\n",
        "\n",
        "    # Process the file\n",
        "    process_file(input_file_path, output_file_path)\n",
        "\n",
        "    # Open the file\n",
        "    with open(output_file_path, 'r') as file:\n",
        "        # Read the file content\n",
        "        content = file.read()\n",
        "\n",
        "    # Split the content into words\n",
        "    words = content.split()\n",
        "\n",
        "    # Count word occurrences\n",
        "    word_counts = count_word_occurrences(words)\n",
        "\n",
        "    # Print the five most common words and their occurrences\n",
        "    print_common_words(word_counts, 5)\n",
        "\n",
        "    # Print the five least common words and their occurrences\n",
        "    print_least_common_words(word_counts, 5)\n",
        "\n",
        "if __name__ == \"__main__\":\n",
        "    main()"
      ],
      "metadata": {
        "id": "JYvdEiTZLMsB",
        "outputId": "58f4e220-f538-4933-f30d-ab36988f12ba",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "5 most common words:\n",
            "the: 14\n",
            "and: 9\n",
            "i: 9\n",
            "of: 8\n",
            "is: 7\n",
            "5 least common words:\n",
            "land: 1\n",
            "look: 1\n",
            "at: 1\n",
            "crowds: 1\n",
            "watergazers: 1\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "zCsdoqzUNipK"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}